#! /usr/bin/env python
# -*- coding: utf-8 -*-
from sys import argv
import re
from random import choice
from openpyxl import Workbook
from openpyxl import load_workbook
from choices import NAMES, PHONE_NUMBER


def loadfile(filename):
    """
    将文件内容加载到内存
    :param filename:
    :return: 数据, 最大行数， 最大列数
    """
    # 打开 xlsx
    wb = load_workbook(filename)

    # 操作第一张表
    ws = wb.worksheets[0]

    # 获得最大的行数, 与列数
    max_row = ws.max_row
    max_column = ws.max_column

    # 将xlsx文件读到内存
    lists = []
    for row in ws.iter_rows(min_row=1, max_col=max_column, max_row=max_row):
        tmp = []
        for cell in row:
            values = cell.value

            # 有些列是空的，但读出来是None属性, 生成数据时不能显示None
            if values is None:
                values = ''
            tmp.append(str(values))
        lists.append(tmp)
    return lists, max_row, max_column


def savefile(data, max_row):
    """
    实例化数据，生成文本
    :param data: 数据
    :param max_row: 文本最大行数
    :return: None
    """
    wb = Workbook()
    ws = wb.active
    for row in range(0, max_row):
        ws.append(data[row])
    wb.save('{}Handle.xlsx'.format(argv[1]))
    exit('程序结束')


def zj1(data, column):
    """正则(姓名)
    效果:保留中文或者大小写英文字母,去空格, 去掉关键字：收、姓名、电话
        如果名字为空随机取一个名字
    """
    reinfo = re.compile(r'[\u4e00-\u9fa5_a-zA-Z]*')
    reinfo2 = re.compile(r'[收,姓名,电话]*')
    for infos in data:
        infos[column] = "".join(
            reinfo.findall(infos[column])
        )
        infos[column] = reinfo2.sub('', infos[column])
        # 指定索引位置为空 并且 整个列表不为空，随机选择一个名字
        if not infos[column] and set(infos) != {''}:
            infos[column] = choice(NAMES)
    return data


def zj2(data, column):
    """正则(号码)
    去掉所有空格，校验号码合法性,
    不合法在已有的电话词库里随机取一个电话
    :param data:
    :param columu:
    :return:
    """
    reinfo = re.compile(
        r'[0-9]*'
    )
    reinfo1 = re.compile(
        r'^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$'
    )
    for infos in data:
        infos[column] = "".join(
            reinfo.findall(infos[column])
        )
        # 匹配不到符合的号码，整个列表不为空. 从字典中随机取一个填充。
        if not reinfo1.match(infos[column]) and set(infos) != {''}:
            infos[column] = choice(PHONE_NUMBER)
    return data


def factory(data, column, max_column, max_row, number):
    """
    工厂方法
    :param data: 数据
    :param column: 操作的列
    :param max_column: 文本最大的列数
    :param munber: 使用正则的数字代号
    :return: 操作后的数据 或 结束保存文本
    """
    column = int(column)
    number = int(number)
    if max_column < column:
        raise ValueError('错误---输入的列数大于xlsx文件列数')
    elif number == 0:
        return savefile(data, max_row)
    elif number == 1:
        edit = zj1
    elif number == 2:
        edit = zj2
    return edit(data, column)


def factory_to(data, column, max_column, max_row, number):
    """
    对工厂方法的补充、封装，捕捉错误
    :param data: 数据
    :param column: 操作的列
    :param max_column: 文本最大列数
    :param max_row: 文本最大的行数
    :param number: 使用正则的数字代号
    :return: 操作后的数据 或 结束保存文本
    """
    factores = None
    try:
        factores = factory(data, column, max_column, max_row, number)
    except ValueError as ve:
        print(ve)
    return factores


if __name__ == '__main__':
    info = """选择要执行的正则
    0: 保存文件并退出
    1: 正则(姓名)
        效果:保留中文或者大小写英文字母,去空格, 去掉关键字：收、姓名、电话
            如果该单元格为空从姓名库中随机抽取一个名字填充
    2: 正则(手机号码)
        效果:去掉所有空格，校验号码合法性,
            如果不合法在已有的电话词库里随机抽取一个电话填充
    """
    datas, max_rows, max_columns = loadfile(argv[1])
    while True:
        columns = input('选择要操作的列数,从0开始计数: ')
        numbers = input(info)
        datas = factory_to(datas, columns, max_columns, max_rows, numbers)
